package com.hmjk.health.card;

import java.util.ArrayList;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import com.hmjk.health.HealthApp;
import com.hmjk.health.R;
import com.hmjk.health.background.DataManager;
import com.hmjk.health.home.DeviceManagerEdit;
import com.hmjk.health.map.MapActivity;
import com.hmjk.health.util.DEV_DATA;
import com.hmjk.health.util.DEV_FACE;
import com.hmjk.health.util.DEV_POWER;
import com.hmjk.health.util.DEV_SET;
import com.hmjk.health.util.LOCATION_INFO;
import com.hmjk.health.util.LocationTimeScanner;
import com.hmjk.health.views.CardAddressRoom;
import com.hmjk.health.views.RefreshLayout;
import com.hmjk.health.views.RefreshLayout.OnRefreshListener;
import com.hmjk.health.views.RoundImageView;

import android.app.Activity;
import android.content.Intent;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.v4.app.Fragment;
import android.text.format.Time;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;

public class CardFragment extends Fragment implements OnClickListener{
	private final String TAG = CardFragment.class.getSimpleName();
	
	private final int MAX_ADDR_NUM = 40;
	
	private HealthApp mApp = null;
	private boolean attached = false;
	private DEV_DATA mDev = null;
	private int mTotal = 0;
	//cards views
	private RefreshLayout refresh;
	//private LinearLayout mCardView;
	private TextView mPage;
	private RoundImageView mPic;
	private TextView mWarning;
	private TextView mError;
	private TextView mBattery;
	
	private DEV_SET mSetData;
	private int queryLocastatus = 0; //0 not query, 1 querying 2 finish
	private int queryPowerstatus = 0; //0 not query, 1 querying 2 finish
	private CardAddressRoom mAddressRoom = null;
	private JSONArray mLocArray = null;
	private LocationTimeScanner scanner = null;
	private View.OnClickListener mRoomListener;
	
	private void logd(String info){
		Log.d(TAG,info);
	}
	
	public CardFragment(HealthApp app){
		super();
		mApp = app;
	}
	
	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){
		//mApp = (HealthApp)getActivity().getApplication();
		Bundle args = getArguments();
		
		mDev = (DEV_DATA) args.getSerializable("dev");
		logd("onCreateView:" + mDev.index);
		mTotal = args.getInt("total");
		
		View v = inflater.inflate(R.layout.card_item, container, false);
		/* views for card start */
		//mCardView = (LinearLayout) findViewById(R.id.cardview);
		
		mPic = (RoundImageView)v.findViewById(R.id.photo);
		mError = (TextView)v.findViewById(R.id.err_status);
		mWarning = (TextView)v.findViewById(R.id.warning_status);
		mBattery = (TextView)v.findViewById(R.id.battery);
		ImageView map = (ImageView) v.findViewById(R.id.map);
		ImageView call = (ImageView) v.findViewById(R.id.call);
		map.setOnClickListener(this);
		call.setOnClickListener(this);
		
		mPage = (TextView) v.findViewById(R.id.pageIndex);
		if(mTotal == 1){
			mPage.setVisibility(View.GONE);
		}else{
			mPage.setVisibility(View.VISIBLE);
			mPage.setText(""+(mDev.index+1)+"/"+mTotal);
		}
		
		refresh = (RefreshLayout)v.findViewById(R.id.refresh_root);
		refresh.initScroll();
		refresh.setOnRefreshListener(new CardRefreshListener());
		/* views for card end*/
		
		mAddressRoom = (CardAddressRoom) v.findViewById(R.id.addr_room);
		mRoomListener = new View.OnClickListener() {
			
			@Override
			public void onClick(View arg0) {
				//pop win list
				if((mLocArray != null) && (scanner != null)){
					ArrayList<JSONObject> arr = scanner.getSortedArray();
					if((arr != null) && (arr.size() > 0))
						AddressListDialog.open(getActivity(), arr);
				}
			}
		};
		
		retrieveLocations();
		return v;
	}
	
	public void queryLocationAndPower(String tid, boolean force){
		logd("queryLocationAndPower queryLocastatus=" + queryLocastatus + " force= "+force);
		if((queryLocastatus == 0) || force){
			boolean update = false;
			boolean ok = mApp.getDataManager().refreshData(DataManager.F_DEVICE_LOCATION, tid);
			if(ok){
				logd("queryLocation querying");
				queryLocastatus = 1;
				update = true;
			}else{
				logd("queryLocation no need");
				//if(querystatus != 2)
				//	update = true;
				queryLocastatus = 2;
			}
			if(update)
				updateLocationView();
		}
		
		logd("queryLocationAndPower queryPowerstatus=" + queryPowerstatus + " force= "+force);
		if((queryPowerstatus == 0) || force){
			boolean update = false;
			boolean ok = mApp.getDataManager().refreshData(DataManager.F_DEVICE_POWER, tid);
			if(ok){
				logd("queryPower querying");
				queryPowerstatus = 1;
				update = true;
			}else{
				logd("queryPower no need");
				//if(querystatus != 2)
				//	update = true;
				queryPowerstatus = 2;
			}
		}
	}
	
	private void retrieveLocations(){
		String[] args = new String[1];
		args[0] = mDev.id;
		mLocArray = null;
		LOCATION_INFO[] arr = (LOCATION_INFO[]) mApp.getDataManager().checkData(DataManager.F_DEVICE_LOCATION, args);
		if((arr != null) && (arr.length > 0) && (arr[0] != null)){
			refresh.setUpdateTime(arr[0].upTime);
			mLocArray = arr[0].createJSONArray();
		}
	}
	
	private void queryLocationDone(boolean updated){
		queryLocastatus = 2;
		if(updated){
			retrieveLocations();
		}
		updateLocationView();
	}
	
	public void updateArgs(Bundle args){
		mDev = (DEV_DATA) args.getSerializable("dev");
		mTotal = args.getInt("total");
		
		if(!attached)
			return;
		
		if(mPage == null)
			return;
		
		if(mTotal == 1){
			mPage.setVisibility(View.GONE);
		}else{
			mPage.setVisibility(View.VISIBLE);
			mPage.setText(""+(mDev.index+1)+"/"+mTotal);
		}
		
		if(!refresh.isRefreshing()){
			updateStatusView();
			updatePowerView();
		}
	}
	
	private void updateView(){
		if(mDev == null)
			return;
		
		String[] args = new String[1];
		args[0] = mDev.id;
		DEV_FACE face = (DEV_FACE) mApp.getDataManager().checkData(DataManager.F_DEVICEFACE, args);
		if(face == null){
			mPic.setImageResource(R.drawable.default_photo);
			mPic.setType(RoundImageView.TYPE_RECT);
			mPic.setBackgroundResource(R.drawable.round_photo_bg);	
		}else if((face.bitmap != null) && !face.bitmap.isRecycled()){
			mPic.setImageBitmap(face.bitmap);
			mPic.setType(RoundImageView.TYPE_ROUND);
			mPic.setBackgroundColor(getResources().getColor(R.color.TRANSPARENT));
		}else{
			mPic.setImageResource(R.drawable.default_photo);
			mPic.setType(RoundImageView.TYPE_RECT);
			mPic.setBackgroundResource(R.drawable.round_photo_bg);
		}
		
		updateStatusView();
		updatePowerView();
	}
	
	private void updatePowerView(){
		String args[] = new String[1];
		args[0] = mDev.id;
		DEV_POWER[] powers = (DEV_POWER[]) mApp.getDataManager().checkData(DataManager.F_DEVICE_POWER, args);
		if((powers != null) && (powers[0] != null) && (powers[0].power >= 0)){
			int bat_img = getBatteryImgRes(powers[0].power);
			mBattery.setText(""+powers[0].power+"%");
			Drawable[] drawables = mBattery.getCompoundDrawables();
			Rect rect = drawables[0].getBounds();
			Drawable newdraw = getResources().getDrawable(bat_img);
			newdraw.setBounds(rect);
			mBattery.setCompoundDrawables(newdraw, null, null, null);
		}else{
			mBattery.setText("?");
			Drawable[] drawables = mBattery.getCompoundDrawables();
			Rect rect = drawables[0].getBounds();
			Drawable newdraw = getResources().getDrawable(R.drawable.bat_icon_unknown);
			newdraw.setBounds(rect);
			mBattery.setCompoundDrawables(newdraw, null, null, null);
		}
	}
	
	private void updateLocationView(){
		if(!attached)
			return;
		if(mAddressRoom == null)
			return;
		
		logd("updateLocationView");
		
		if(queryLocastatus == 1){
			mAddressRoom.setLoading(true);
			return;
		}else{
			mAddressRoom.setLoading(false);
		}
		
		mAddressRoom.clearAll();
		if(mLocArray!=null){
			try {
				if(scanner == null)
					scanner = new LocationTimeScanner(mLocArray);
				else
					scanner.resetData(mLocArray);
				int count = 0;
				boolean hasMore = false;
				
				while(scanner.hasNext()){
					if(count >= MAX_ADDR_NUM){
						hasMore = true;
						break;
					}
					String date = scanner.checkNextDateString();
					mAddressRoom.addDateView(date);
					JSONArray arr = scanner.get();
					int l = arr.length();
					for(int i = 0; i < l; i++){
						if(count >= MAX_ADDR_NUM){
							hasMore = true;
							break;
						}
						JSONObject e = arr.getJSONObject(i);
						String addr = "";
						if(e.has("addr"))
						  addr = e.getString("addr");
						long time = e.getLong("time");
						Time t = new Time();
						t.setToNow();
						t.set(time);
						String timestr = String.format("%02d:%02d", t.hour, t.minute);
						mAddressRoom.addAddressView(timestr, addr, e.getInt("flag"));
						count ++;
					}
				}
				if(count > 0){
					if(hasMore){
						mAddressRoom.hasMore(mRoomListener);
					}else{
						mAddressRoom.hasMore(null);
					}
				}
			} catch (JSONException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		mAddressRoom.checkEmpty();
	}
	
	@Override
	public void onAttach(Activity a){
		logd("onAttach");
		super.onAttach(a);
		attached = true;
	}
	
	@Override
	public void onDetach(){
		logd("onDetach:"+mDev.index);
		attached = false;
		super.onDetach();
	}
	
	private void updateStatusView(){
		if(!attached)
			return;
		
		if(mDev.status == 1){
			mError.setVisibility(View.GONE);
		}else if(mDev.status == 0){
			mError.setVisibility(View.VISIBLE);
			mError.setText(R.string.device_disabled);
		}else if(mDev.status == 2){
			mError.setVisibility(View.VISIBLE);
			mError.setText(R.string.device_frozen);
		}
		
		boolean isactive = true;
		
		if(mSetData != null){
			isactive = mSetData.active;
		}
		if(isactive == false){
			mWarning.setVisibility(View.VISIBLE);
			if(mDev.admin == 2){
				mWarning.setText(R.string.dev_noadmin);
			}else{
				mWarning.setText(R.string.dev_notactive);
			}
		}else if(mDev.admin == 2){
			mWarning.setVisibility(View.VISIBLE);
			mWarning.setText(R.string.dev_noadmin);
		}else{
			mWarning.setVisibility(View.GONE);
		}
	}
	
	private int getBatteryImgRes(int percent){
		if(percent < 10){
			return R.drawable.bat_icon_000;
		}else if(percent < 20){
			return R.drawable.bat_icon_010;
		}else if(percent < 30){
			return R.drawable.bat_icon_020;
		}else if(percent < 40){
			return R.drawable.bat_icon_030;
		}else if(percent < 50){
			return R.drawable.bat_icon_040;
		}else if(percent < 60){
			return R.drawable.bat_icon_050;
		}else if(percent < 70){
			return R.drawable.bat_icon_060;
		}else if(percent < 80){
			return R.drawable.bat_icon_070;
		}else if(percent < 90){
			return R.drawable.bat_icon_080;
		}else if(percent < 100){
			return R.drawable.bat_icon_090;
		}else{
			return R.drawable.bat_icon_100;
		}
	}
	
	@Override
	public void onResume(){
		super.onResume();
		updateData();
		updateView();
		updateLocationView();
	}
	
	public void focusChange(boolean focus){
		refreshing = null;
		if(refresh != null)
		refresh.stopRefreshing();
		
		if(focus && (mDev != null)){
			queryLocationAndPower(mDev.id, false);
		}
		
	}
	
	private void updateData(){
		mSetData = null;
		String[] arg1 = new String[2];
		arg1[0] = "DEV_TID";
		arg1[1] = mDev.id;
		JSONObject devjson = (JSONObject) mApp.getDataManager().checkData(DataManager.F_DEVICELIST, arg1);
		if(devjson != null){
			try{
				JSONArray ar = devjson.getJSONArray("array");
				if(ar.length() > 0){
					JSONObject e = ar.getJSONObject(0);
					mDev.id = e.getString("tid");
					mDev.name = e.getString("name");
						
					String ss = e.getString("status");
					mDev.status = Integer.parseInt(ss);
						
					mDev.type = e.getString("type");
						
					String a = e.getString("admin");
					mDev.admin = Integer.parseInt(a);
				}
			} catch (JSONException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}
		}
		String[] arg2 = new String[1];
		arg2[0] = mDev.id;
		
		DEV_SET[] data = (DEV_SET[]) mApp.getDataManager().checkData(DataManager.F_DEVICE_SETTINGS, arg2);
		if(data != null){
			mSetData =  data[0];
		}
	}
	
	private String refreshing = null;
	class CardRefreshListener implements OnRefreshListener{

		@Override
		public void onRefresh() {
			refreshing = null;
			if(((CardsActivity)getActivity()).refreshList()){
				refreshing = new String(DataManager.F_DEVICELIST);
			}else{
				refreshOthers();
			}
			
			if(refreshing == null){
				Message m = mhandler.obtainMessage(MSG_REFRESH_CARD_AUTO_CLOSE);
				mhandler.sendMessageDelayed(m, 500);
			}
		}
	}
	
	private void refreshOthers(){
		boolean ok = mApp.getDataManager().refreshData(DataManager.F_DEVICEFACE, mDev.id);
		if(ok){
			refreshing = new String(DataManager.F_DEVICEFACE);
		}
		
		ok = mApp.getDataManager().refreshData(DataManager.F_DEVICE_SETTINGS, mDev.id);
		if(ok){
			if(refreshing == null)
				refreshing = new String(DataManager.F_DEVICE_SETTINGS);
			else
				refreshing += ":" + DataManager.F_DEVICE_SETTINGS;
		}
		
		queryLocationAndPower(mDev.id, true);
	}
	
	public void refreshResult(String tag, boolean update){
		if(mDev == null){
			logd("refreshResult mDev == null");
			return;
		}
		
		if(DataManager.F_DEVICELIST.equals(tag)){
			if((refreshing != null) && refreshing.equals(tag)){
				refreshing = null;
				refreshOthers();
				if(refreshing == null){
					updateData();
					cancelRefresh();
					updateView();
				}
			}
		}else if(DataManager.F_DEVICEFACE.equals(tag) || DataManager.F_DEVICE_SETTINGS.equals(tag)){
			if(refreshing != null){
				updateRefreshFlag(tag);
				if(refreshing == null){
					updateData();
					cancelRefresh();
					updateView();
				}
			}else if(update){
				if(DataManager.F_DEVICE_SETTINGS.equals(tag)){
					updateData();
				}
				updateView();
			}
		}else if(DataManager.F_DEVICE_LOCATION.equals(tag)){
			queryLocationDone(update);
		}else if(DataManager.F_DEVICE_POWER.equals(tag)){
			if(update)
				updatePowerView();
		}
	}
	
	private void updateRefreshFlag(String clear){
		if(refreshing.contains(clear)){
			String[] ss = refreshing.split(":");
			String flag = "";
			for(String s:ss){
				if(s.equalsIgnoreCase(clear) == false){
					if(flag.equals("") == false){
						flag += ":";
					}
					flag += s;
				}
			}
			if(flag.trim().isEmpty())
				refreshing = null;
			else{
				refreshing = flag.trim();
			}
		}
	}
	
	private final int MSG_REFRESH_CARD_AUTO_CLOSE = 311;
	
	private Handler mhandler = new Handler(){
		@Override
		public void handleMessage(Message msg){
			switch(msg.what){
			case MSG_REFRESH_CARD_AUTO_CLOSE:{
				cancelRefresh();
			}
			break;
			}
		}
	};
	
	public boolean cancelRefresh(){
		refreshing = null;
		if((refresh != null) && refresh.isRefreshing()){
			refresh.stopRefreshing();
			return true;
		}
		return false;
	}
	
	public boolean isRefreshing(){
		if(refresh != null)
			return refresh.isRefreshing();
		
		return false;
	}

	@Override
	public void onClick(View v) {
		switch(v.getId()){
		case R.id.map:{
			//TODO:open map activity
            
			Intent i = new Intent(getActivity(),MapActivity.class);
			startActivity(i);
			getActivity().finish();		
		}break;
		case R.id.call:{
			if(mSetData == null)
				break;
			
			String mobile = mSetData.mobile;
			if((mobile == null) || mobile.trim().isEmpty()){
				if(mDev.admin == 1){
					mApp.showConfirmDialog(getActivity(), getResources().getString(R.string.setPhoneFirst), new OnClickListener() {
						
						@Override
						public void onClick(View view) {
							if(view.getId() == R.id.alert_but1){
								Intent i = new Intent(getActivity(),DeviceManagerEdit.class);
								i.putExtra("dev", mDev);
								startActivity(i);
							}
						}
					});	
				}else{
					mApp.showAlertDialog(getActivity(), R.string.noPhoneNumber);
				}
				break;
			}
			
				
			Intent intent=new Intent();
			intent.setAction(Intent.ACTION_DIAL);   //android.intent.action.DIAL
			intent.setData(Uri.parse("tel:"+ mSetData.mobile));

			startActivity(intent);
		}break;
		}
	}
}
